package com.jcli.novel_p;

import java.io.*;
import java.util.*;

/**
 * 2.0往properties文件写入数据的功能（更新版
 * 1.将主要功能模块封装成方法： 将不同功能的代码块封装成方法，使代码更模块化和易读。这将有助于提高代码的可维护性和可重用性。
 * 2.改进键值对的排序： 代码中使用了自定义的比较器来对键值对进行排序，但您可以通过使用Java 8的流和Lambda表达式来更简洁地实现排序。
 * 3.异常处理： 在代码中有一些可能抛出异常的地方，应该进行适当的异常处理和错误信息提示。
 * 4.关闭资源： 在使用完 Scanner 和文件资源后，应该在 finally 块中关闭这些资源，以确保资源得到正确释放。
 * 5.将文件路径提取为常量： 避免多次使用硬编码的文件路径，将文件路径提取为一个常量，以便在代码中统一管理。
 */
public class WriteToProperties02 {
    private static final String FILE_PATH = "src/main/resources/config.properties";

    public static void main(String[] args) {
        Properties properties = loadProperties();

        // 打印初始的所有键值对
        printProperties(properties);

        Scanner scanner = new Scanner(System.in);

        while (true) {
            int initialSize = properties.size();//获取初始属性数量。
            System.out.print("请输入要添加的数据 (格式：键=值)，或输入 'exit' 退出： ");
            String input = scanner.nextLine().trim();

            if (input.equalsIgnoreCase("exit")) {
                break;
            }

            String[] keyValue = input.split("=");
            if (keyValue.length != 2) {
                System.out.println("输入格式无效，请重新输入。");
                continue;
            }

            // 新增或跳过键值对
            String key = keyValue[0];
            String value = keyValue[1];

            handleKeyValuePair(properties, key, value);

            // 排序并按照值进行中文多音字排序
            sortPropertiesByValue(properties);

            // 保存到文件
            savePropertiesToFile(properties);

            // 打印最终的所有键值对
            printProperties(properties);

        }

        // 关闭资源
        scanner.close();
    }

    private static Properties loadProperties() {
        Properties properties = new Properties();
        try (InputStream inputStream = new FileInputStream(FILE_PATH)) {
            properties.load(new InputStreamReader(inputStream, "UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return properties;
    }

    private static void handleKeyValuePair(Properties properties, String key, String value) {
        if (properties.containsKey(key)) {
            // 如果键已经存在，则不录入
            System.out.println("键 '" + key + "' 已存在，跳过该项。");
        } else if (properties.containsValue(value)) {
            // 查找是否已有相同的值
            Set<String> keys = properties.stringPropertyNames();
            boolean valueExistsWithDifferentKey = false;

            for (String existingKey : keys) {
                if (properties.getProperty(existingKey).equals(value) && !existingKey.equals(key)) {
                    valueExistsWithDifferentKey = true;
                    break;
                }
            }

            if (valueExistsWithDifferentKey) {
                System.out.println("值 '" + value + "' 已存在，但键不同。");
                System.out.print("是否录入已有的键值对？(yes/no): ");
                Scanner scanner = new Scanner(System.in);
                String choice = scanner.nextLine().trim().toLowerCase();
                scanner.close();
                if (choice.equals("yes")) {
                    properties.setProperty(key, value);
                    System.out.println("键 '" + key + "' ='" + value + "' 已录入成功。");
                } else {
                    System.out.println("已跳过键 '" + key + "' 的录入。");
                }
            } else {
                System.out.println("值 '" + value + "' 已存在，但键相同，跳过该项。");
            }
        } else {
            properties.setProperty(key, value);
            System.out.println("键 '" + key + "' ='" + value + "' 已录入成功。");
        }
    }

    private static void sortPropertiesByValue(Properties properties) {
        // 使用Java 8的流和Lambda表达式按值的首字母进行排序
        properties = properties.entrySet()
                .stream()
                .sorted(Comparator.comparing(e -> ((String) e.getValue()).substring(0, 1)))
                .collect(Properties::new, (p, e) -> p.put(e.getKey(), e.getValue()), Properties::putAll);
    }

    private static void savePropertiesToFile(Properties properties) {
        try (OutputStream outputStream = new FileOutputStream(FILE_PATH)) {
            properties.store(new OutputStreamWriter(outputStream, "UTF-8"), null);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void printProperties(Properties properties) {
        System.out.println("当前的键值对:");
        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
            System.out.println(entry.getKey() + "=" + entry.getValue());
        }
    }
}
